package cn.fintecher.pangolin.service.manage.request;

import cn.fintecher.pangolin.common.enums.BaseSelect;
import cn.fintecher.pangolin.common.enums.StrategyType;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.json.JSONArray;
import org.json.JSONObject;

import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * @Auther: xiaqun
 * @Description: 策略预览请求
 * @Date: 16:30 2019/9/23
 */

@Data
public class StrategyPreviewRequest {
    @ApiModelProperty(value = "策略类型")
    private StrategyType strategyType;

    @ApiModelProperty(value = "委托方集合")
    private List<String> principalIds;

    @ApiModelProperty(value = "委案城市集合")
    private String cities;

    @ApiModelProperty(value = "公式JSON")
    private String formulaJson;

    public BoolQueryBuilder getBuilder() throws Exception {
        BoolQueryBuilder builder = new BoolQueryBuilder();
        builder.must(QueryBuilders.matchPhraseQuery("isDistribute.keyword", BaseSelect.NO.name()));
        builder.mustNot(QueryBuilders.existsQuery("strategyId.keyword"));
        if (Objects.nonNull(this.principalIds) && !this.principalIds.isEmpty()) {
            builder.must(QueryBuilders.termsQuery("principalId.keyword", this.principalIds));
        }
        if (StringUtils.isNotBlank(this.cities)) {
            List<String> city = Arrays.asList(this.cities.split(","));
            List<String> list = new ArrayList<>();
            city.forEach(e -> {
                if (StringUtils.isNotBlank(e)) {
                    list.add(e);
                }
            });
            if (!list.isEmpty()) {
                builder.must(QueryBuilders.termsQuery("city.keyword", list));
            }
        }
        if (StringUtils.isNotBlank(this.formulaJson)) {
            BoolQueryBuilder builder1 = new BoolQueryBuilder();
            analysisFormula(this.formulaJson, builder1);
            builder.must(builder1);
        }
        return builder;
    }

    /**
     * 处理json
     */
    private void analysisFormula(String json, BoolQueryBuilder builder) throws Exception {
        JSONArray jsonArray = new JSONArray(json);
        for (int i = 0; i < jsonArray.length(); i++) {
            JSONObject jsonObj = jsonArray.getJSONObject(i);
            if (jsonObj.getBoolean("leaf")) {
                String variable = jsonObj.get("variable").toString();
                int flag = processSymbol(jsonObj.get("symbol").toString());
                String bracket = jsonObj.get("bracket").toString();
                int relation = -1;
                if (!bracket.equals("null")) {
                    relation = processRelation(bracket);
                }
                if (flag == 0) {
                    if (jsonObj.get("variable").toString().equals("delegationDate") || jsonObj.get("variable").toString().equals("endCaseDate")) {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    } else {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    }
                } else if (flag == 1) {
                    if (jsonObj.get("variable").toString().equals("delegationDate") || jsonObj.get("variable").toString().equals("endCaseDate")) {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    } else {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).gte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    }
                } else if (flag == 2) {
                    if (jsonObj.get("variable").toString().equals("delegationDate") || jsonObj.get("variable").toString().equals("endCaseDate")) {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).lt((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).lt((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lt((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lt((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                            builder.should(builder1);
                        }
                    } else {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).lt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).lt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lt(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    }
                } else if (flag == 3) {
                    if (jsonObj.get("variable").toString().equals("delegationDate") || jsonObj.get("variable").toString().equals("endCaseDate")) {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).lte((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).lte((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lte((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lte((long) processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString()) + 86400000L));
                            builder.should(builder1);
                        }
                    } else {
                        if (relation == 0 || relation == -1) {
                            builder.must(QueryBuilders.rangeQuery(variable).lte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 1) {
                            builder.should(QueryBuilders.rangeQuery(variable).lte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        } else if (relation == 2) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.must(builder1);
                        } else if (relation == 3) {
                            BoolQueryBuilder builder1 = new BoolQueryBuilder();
                            builder1.must(QueryBuilders.rangeQuery(variable).lte(processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                            builder.should(builder1);
                        }
                    }
                } else {
                    if (relation == 0 || relation == -1) {
                        builder.must(QueryBuilders.matchPhraseQuery(variable, processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                    } else if (relation == 1) {
                        builder.should(QueryBuilders.matchPhraseQuery(variable, processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                    } else if (relation == 2) {
                        BoolQueryBuilder builder1 = new BoolQueryBuilder();
                        builder1.must(QueryBuilders.matchPhraseQuery(variable, processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        builder.must(builder1);
                    } else if (relation == 3) {
                        BoolQueryBuilder builder1 = new BoolQueryBuilder();
                        builder1.must(QueryBuilders.matchPhraseQuery(variable, processValue(jsonObj.get("variable").toString(), jsonObj.get("value").toString())));
                        builder.should(builder1);
                    }
                }
            } else {
                BoolQueryBuilder builder1 = new BoolQueryBuilder();
                analysisFormula(jsonObj.getJSONArray("children").toString(), builder1);
                builder.must(builder1);
            }
        }
    }

    /**
     * 处理符号
     */
    private int processSymbol(String symbol) {
        switch (symbol) {
            case ">":
                return 0;
            case ">=":
                return 1;
            case "<":
                return 2;
            case "<=":
                return 3;
            case "==":
                return 4;
            default:
                return 4;
        }
    }

    /**
     * 处理值
     */
    private Object processValue(String variable, String value) throws ParseException {
        switch (variable) {
            case "overdueAmtTotal":
            case "leftAmt":
                return Double.parseDouble(value);
            case "overduePeriods":
            case "overdueDays":
                return Integer.parseInt(value);
            case "delegationDate":
            case "endCaseDate":
                return ZWDateUtil.getFormatDate(value).getTime();
            default:
                return 0;
        }
    }

    /**
     * 处理关系
     */
    private int processRelation(String str) {
        switch (str) {
            case "并且":
            case ")并且":
                return 0;
            case "或者":
            case ")或者":
                return 1;
            case "并且(":
            case ")并且(":
                return 2;
            case "或者(":
            case ")或者(":
                return 3;
            default:
                return 0;
        }
    }
}
